using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Zhao.Common.JWT;

namespace Zhao.Arena.MiniProgram.Api.Utility.Jwt
{
    /// <summary>
    /// JWT服务类
    /// 提供JWT令牌的生成和验证功能
    /// </summary>
    public class JwtService
    {
        private readonly JWTTokenOptions _jwtSettings;
        private readonly ILogger<JwtService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="jwtSettings">JWT配置选项</param>
        /// <param name="logger">日志记录器</param>
        public JwtService(
            IOptions<JWTTokenOptions> jwtSettings,
            ILogger<JwtService> logger)
        {
            _jwtSettings = jwtSettings.Value;
            _logger = logger;
        }

        /// <summary>
        /// 生成JWT令牌
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="userName">用户名称</param>
        /// <returns>JWT令牌字符串</returns>
        /// <remarks>
        /// 生成的令牌包含以下信息：
        /// 1. 用户ID（作为NameIdentifier声明）
        /// 2. 过期时间（从配置中读取）
        /// 3. 使用配置的密钥进行签名
        /// </remarks>
        public string GenerateToken(string userId, string userName)
        {
            // 创建令牌的声明（Claims）
            var claims = new[]
            {
                new Claim(ClaimTypes.Sid, userId),
                new Claim(ClaimTypes.Name,userName)
            };

            //准备加密key
            SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecurityKey!));

            //Sha256 加密方式
            SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            JwtSecurityToken JwtAccessToken = new JwtSecurityToken(
                    issuer: _jwtSettings.Issuer,
                    claims: claims.ToArray(),
                    expires: DateTime.Now.AddMinutes(_jwtSettings.ExpireMinutes),//10分钟有效期
                    signingCredentials: creds);

            // 将令牌转换为字符串
            return new JwtSecurityTokenHandler().WriteToken(JwtAccessToken);
        }
    }
}